﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Entity = SetupLauncher.Domain.Entity;
using Logger = SetupLauncher.Domain.Logger;
using Config = SetupLauncher.Domain.Configuration;
using SetupLauncher.Domain.Exceptions;

namespace SetupLauncher.UI
{
    public partial class Configuration : Form, Logger.ILoggable
    {
        List<Entity.Product> _products = new List<Entity.Product>();
        Config.IConfiguration _config;

        private string FilePath { get; set; }

        public Configuration()
        {
            _config = Config.ConfigurationFactory.Create(this);
            InitializeComponent();
        }

        private void Initialize()
        {
            if (string.IsNullOrEmpty(this.FilePath))
            {
                WriteAlert("É necessário selecionar um local para carregar as configurações");
                return;
            }

            _config.Load(this.FilePath);
            if(_config.Products != null)
                _products = _config.Products;

            LoadList();
        }

        private void LoadList()
        {
            lstProducts.Items.Clear();
            foreach (Entity.Product product in _products)
                lstProducts.Items.Add(product);
        }

        private void Save()
        {
            CreatePath();
            _config.Erase();
            foreach (Object item in lstProducts.Items)
            {
                Entity.Product product = item as Entity.Product;
                if (product != null)
                {
                    _config.AddProduct(product);
                }
            }

            if (string.IsNullOrEmpty(this.FilePath))
            {
                WriteAlert("É necessário selecionar um local para salvar o arquivo");
                return;
            }
            _config.Save(this.FilePath);
            MessageBox.Show("Arquivo salvo com Sucesso", "SetupLaunch", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }

        private void CreatePath()
        {
            if (!string.IsNullOrEmpty(this.FilePath))
                return;

            SaveFileDialog saveFile = new SaveFileDialog();
            saveFile.CheckPathExists = true;
            saveFile.Filter = FilterDialog();
            saveFile.ShowDialog();
            this.FilePath = saveFile.FileName;
            txtPath.Text = this.FilePath;
        }

        private string FilterDialog()
        {
            return "Xml files (*.xml)|*.xml";
        }

        private void SelectObject()
        {
            if (lstProducts.SelectedItem != null)
            {
                propGrid.SelectedObject = lstProducts.SelectedItem;
                propGrid.Focus();
            }
        }

        private void NewProduct()
        {
            Entity.Product product = new Entity.Product();
            product.Name = "<<Novo>>";
            lstProducts.Items.Add(product);
            lstProducts.SelectedItem = product;
            SelectObject();
        }

        private void UpdateList()
        {
            Entity.Product product = propGrid.SelectedObject as Entity.Product;
            if (product != null)
            {
                int index = lstProducts.SelectedIndex;
                lstProducts.Items.RemoveAt(index);
                lstProducts.Items.Insert(index, product);
                lstProducts.SelectedIndex = index;
            }
        }

        private void DeleteProduct()
        {
            Entity.Product product = propGrid.SelectedObject as Entity.Product;
            if (product != null)
            {
                int index = lstProducts.SelectedIndex;
                lstProducts.Items.RemoveAt(index);
                if (lstProducts.Items.Count > 0)
                    lstProducts.SelectedIndex = 0;

                SelectObject();
            }
        }

        private void SearchFile()
        {
            OpenFileDialog openFile = new OpenFileDialog();
            openFile.CheckPathExists = true;
            openFile.Filter = FilterDialog();
            openFile.FileName = this.FilePath;
            openFile.ShowDialog();
            this.FilePath = openFile.FileName;
            txtPath.Text = this.FilePath;
            Initialize();
        }

        private void btnSave_Click(object sender, EventArgs e)
        {
            Save();
        }

        private void lstProducts_Click(object sender, EventArgs e)
        {
            SelectObject();
        }

        private void btnNewproduct_Click(object sender, EventArgs e)
        {
            NewProduct();
        }

        private void BeforeDelete(Keys key)
        {
            if (key == Keys.Delete && lstProducts.SelectedIndex >= 0)
            {
                string message = "Deseja excluir o produto selecionado ?";
                DialogResult result = MessageBox.Show(message, "SetupLaucher", MessageBoxButtons.YesNo);
                if (result == DialogResult.Yes)
                    DeleteProduct();
            }
        }

        private void propGrid_PropertyValueChanged(object s, PropertyValueChangedEventArgs e)
        {
            if(e.ChangedItem.Label.Equals("Name", StringComparison.CurrentCultureIgnoreCase))
                UpdateList();
        }

        private void Configuration_KeyDown(object sender, KeyEventArgs e)
        {
            BeforeDelete(e.KeyData);
        }

        private void btnSearchFile_Click(object sender, EventArgs e)
        {
            SearchFile();
        }

        public void WriteException(string message)
        {
            MessageBox.Show(message, this.Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
        }

        public void WriteAlert(List<Validation> validations)
        {
            StringBuilder sb = new StringBuilder();
            sb.AppendLine("Foram encontrados os seguintes problemas:");
            foreach (Validation item in validations)
                sb.AppendLine("- " + item.Description);

            WriteAlert(sb.ToString());
        }

        public void WriteAlert(string message)
        {
            MessageBox.Show(message, this.Text, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
        }

        public void Write(string message)
        {
            
        }
    }
}
